//  目标：Promise 的 then 方法是可以被多次调用的。这里如果有三个 then 的调用，如果是同步回调，那么直接返回当前的值就行；
//    如果是异步回调，那么保存的成功失败的回调，需要用不同的值保存，因为都互不相同。之前的代码需要改进。

//  解决Promise.then 后可以接多个Promise.then

//  思路：将MyPromise2 中储存回调函数的俩个属性  onFulfilledCallback， onRejectedCallback 设置为数组，这样就能储存多个回调函数了
//        当异步任务开始执行的时候，通过循环调用调用数组里面的回调函数。

const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECT = 'reject'

class MyPromise3 {
    constructor(executor) {
        executor(this.resolve, this.reject)
    }

    status = PENDING;

    value = null;

    reason = null;

    // 变为Fulfilled resolve成功的回调数组
    onFulfilledCallbacks = [];
    // 变成REJECT  reject失败的回调数组
    onRejectedCallbacks = [];

    resolve = (value) => {
        if (this.status === PENDING) {
            this.status = FULFILLED;
            this.value = value;

            while (this.onFulfilledCallbacks.length) {  // 如果成功的回调数组长度不为空
                this.onFulfilledCallbacks.shift()(value)   // 弹出数组的首位元素也就是回调函数并执行
            }
        }
    }

    reject = (reason) => {
        if (this.status === PENDING) {
            this.status = REJECT;
            this.reason = reason;

            while (this.onRejectedCallbacks.length) {
                this.onRejectedCallbacks.shift()(reason)
            }
        }
    }


    then(onFulfilled, onRejected) {

        if (this.status === FULFILLED) {
            onFulfilled(this.value)
        } else if (this.status === REJECT) {
            onRejected(this.reason);
        } else if (this.status === PENDING) {
            // 如果为PENDING状态，则表示在异步等待，需要将执行的成功和失败回调函数推入对应回调队列
            this.onFulfilledCallbacks.push(onFulfilled);
            this.onRejectedCallbacks.push(onRejected);

        }
    }

}

const promise = new MyPromise3((resolve, reject) => {
    setTimeout(() => {
        resolve('success')
    }, 2000);
})

promise.then(value => {
    console.log(1)
    console.log('resolve', value)
})

promise.then(value => {
    console.log(2)
    console.log('resolve', value)
})

promise.then(value => {
    console.log(3)
    console.log('resolve', value)
})

